package cn.group7.padserver.service.impl;

import cn.group7.padserver.service.FileService;
import cn.hutool.core.io.FileUtil;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * @author TexBin
 */
@Service
public class FileServiceImpl implements FileService {


    @Value("${ip.dev}")
    private String ip;

    @Value("${port.dev}")
    private String port;


    /**
     * 获取File对象，该对象用于存储文件（相当于开辟一个空间，为存储文件做准备）
     *
     * @param fileName 文件名
     * @return File对象和文件名和文件类型
     */
    @Override
    public Map<String, Object> getFile(String fileName) {
        //获取文件名（无后缀）
        String mainName = FileUtil.mainName(fileName);
        //获取文件后缀
        String suffix = FileUtil.extName(fileName);
        //获取当前项目的路径
        String projectPath = System.getProperty("user.dir");
        //设置服务器文件存储路径
        String filePath = projectPath + "\\files";
        //创建File对象
        File file = new File(filePath + "\\" + mainName + "." + suffix);
        //如果该路径已经有文件存在,另起名
        if (file.exists()) {
            mainName = System.currentTimeMillis() + "-" + mainName;
            file = new File(filePath + "\\" + mainName + "." + suffix);
        }
        //返回文件下载名
        String fileDownloadName = mainName + "." + suffix;
        return Map.of("file", file, "fileDownloadName", fileDownloadName);
    }


    /**
     * 1.上传文件
     *
     * @param file 文件
     * @return 文件地址
     * @throws IOException IO异常
     */
    @Override
    public String upload(MultipartFile file) throws IOException {
        //获取文件的原始名称（xxx.txt/xxx.png...）
        String fileName = file.getOriginalFilename();
        Map<String, Object> map = getFile(fileName);
        File saveFile = (File) map.get("file");
        String fileDownloadName = (String) map.get("fileDownloadName");
        try {
            //存储文件到本地磁盘
            file.transferTo(saveFile);

            //根据文件类型返回一个文件链接的下载地址
            if ("mp4".equals(FileUtil.extName(fileName))) {
                return "http://" + ip + ":" + port + "/video-play/" + fileDownloadName;
            }
            return "http://" + ip + ":" + port + "/file/download/" + fileDownloadName;
        } catch (IOException e) {
            throw new IOException("文件上传失败！");
        }
    }


    /**
     * 2.下载文件
     *
     * @param fileName 文件名
     * @param response 响应
     * @return 是否能够下载
     */
    @Override
    public boolean download(String fileName, HttpServletResponse response) {
        //根据文件名得到文件路径
        String filePath = System.getProperty("user.dir") + "\\files\\" + fileName;
        //判断文件是否存在
        if (FileUtil.exist(filePath)) {
            try {
                // 设置响应的内容类型
                response.setContentType("application/octet-stream");
                // 设置响应头，指定文件名和编码方式
                response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));

                byte[] bytes = FileUtil.readBytes(filePath);
                ServletOutputStream out = response.getOutputStream();
                out.write(bytes);
                out.flush();
                out.close();
                return true;
            } catch (Exception e) {
                System.out.println("无法下载文件！错误：" + e.toString());
                return false;
            }
        }
        System.out.println("不存在该文件！");
        return false;
    }

    /**
     * 3.删除文件
     *
     * @param fileName 文件名
     * @return 是否删除成功
     */
    @Override
    public boolean delete(String fileName) {
        //根据文件名得到文件路径
        String filePath = System.getProperty("user.dir") + "\\files\\" + fileName;
        //判断文件是否存在
        if (FileUtil.exist(filePath)) {
            try {
                //不能删除默认文件
                if ("default.jpg".equals(fileName)) {
                    return false;
                }
                FileUtil.del(filePath);
                return true;
            } catch (Exception e) {
                return false;
            }
        }
        return false;
    }
}
